package cn.zf233.springsecurityjwt.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by zf233 on 2021/7/12
 */
@Component
@Slf4j
public class JwtUtil {

    private static final long DEFAULT_EXPIRE_MILLISECONDS = 2 * 60 * 60 * 1000;
    private static final String SECRET = "secret";

    public String createToken(Map<String, Object> loadMap, long expireMillTime) {
        log.info("准备生成Token");
        if (expireMillTime <= 0) {
            expireMillTime = DEFAULT_EXPIRE_MILLISECONDS;
        }
        log.info("准备生成Token\t负载:" + loadMap + "\t有效期（毫秒）:" + expireMillTime);
        long expire = System.currentTimeMillis() + expireMillTime;
        JWTCreator.Builder builder = JWT.create();
        builder.withJWTId(System.currentTimeMillis() + UUID.randomUUID().toString());
        loadMap.forEach((k, v) -> builder.withClaim(k, String.valueOf(v)));
        builder.withExpiresAt(new Date(expire));
        log.info("生成Token完成");
        return builder.sign(Algorithm.HMAC256(SECRET));
    }

    public String createTokenByUserId(Long userId, long expireMillTime) {
        Map<String, Object> loadMap = new HashMap<>();
        loadMap.put("userId", userId);
        return this.createToken(loadMap, expireMillTime);
    }

    public void verify(String token) {
        JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);  // 如果验证通过，则不会把报错，否则会报错
    }

    public DecodedJWT getToken(String token) {
        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }

    public Long getUserIdByToken(String token) {
        DecodedJWT decoded = this.getToken(token);
        return Long.parseLong(decoded.getClaims().get("userId").asString());
    }
}
